import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  Inject,
  LoggerService,
  NotFoundException
} from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { HttpAdapterHost } from '@nestjs/core'
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'

import { MESSAGES } from '@/constants'
import { IConfig, IRequest } from '@/interfaces'

import { DefaultFilter } from './default.filter'

/**
 * 资源不存在错误处理
 */
@Catch(NotFoundException)
export class NotFoundFilter implements ExceptionFilter {
  constructor(
    @Inject(WINSTON_MODULE_NEST_PROVIDER)
    private readonly loggerService: LoggerService,
    private readonly configService: ConfigService,
    private readonly httpAdapterHost: HttpAdapterHost
  ) {}

  catch(exception: NotFoundException, host: ArgumentsHost) {
    const { httpAdapter } = this.httpAdapterHost
    const { apiPath } = this.configService.get<IConfig['app']>('app')
    const ctx = host.switchToHttp()
    const status = exception.getStatus()
    const req = ctx.getRequest<IRequest>()
    const isApi = req.url.includes(apiPath)

    if (isApi) {
      const message = `${MESSAGES.NOT_FOUND}: ${exception.message}`

      this.loggerService.error(message, exception.stack, DefaultFilter.name)

      httpAdapter.reply(
        ctx.getResponse(),
        {
          status,
          message
        },
        status
      )
    }
  }
}
